﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Timers;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.Media;
using Android.OS;
using Android.Support.Design.Widget;
using Android.Support.V4.App;
using Android.Support.V4.View;
using Android.Support.V4.Widget;
using Android.Support.V7.App;
using Android.Support.V7.Widget;
using Android.Util;
using Android.Views;
using Android.Widget;
using API;
using Com.Gcssloop.Widget;
using FFImageLoading;
using Java.Net;
using mb;
using mb.Droid;
using mb.DroidLib;
using static libmp.DataStore;
using GridLayout = Android.Support.V7.Widget.GridLayout;
using Orientation = Android.Widget.Orientation;

namespace libmp
{
    enum MovieMode
    {
        None,
        InView,
        FullScreen,
    }

    enum PrepareState
    {
        None,
        Loading,
        Succeed,
        Failure,
    }
    static class Extensions
    {
        public static MovieMode toggle(this MovieMode mode)
        {
            return mode == MovieMode.FullScreen?MovieMode.InView : MovieMode.FullScreen;
        }
    }

    class MoviePlayView : ExMovieList
    {
        MyFragment myFragment;
        VideoItem videoItem;

        MovieMode movieMode;
        MediaPlayer player;
        // MyMediaDataSource mediaSource;
        MyFragment playerFragment;
        FrameLayout movieLayout;
        FrameLayout playerLayout;
        LinearLayout rootLayout;
        int bufferingPercent;
        int reloadCount;
        bool startOnResume;
        System.Timers.Timer tmUpdate;
        PrepareState prepareState;

        public static void OpenPlayView(DataStore.VideoItem mi)
        {
            var ctx = StartActivity.This;
            string tag = "MoviePlay";
            var findFrag = ctx.SupportFragmentManager.FindFragmentByTag(tag);
            if (findFrag != null)
            {
                logger.Log("already in movieplayview, skip reopen");
                return;
            }

            var mfrag = new MoviePlayView(mi).CreateFragment();
            var ft = ctx.SupportFragmentManager.BeginTransaction();
            ft.Add(ctx.ContentViewId, mfrag, tag);
            ft.AddToBackStack("play");
            ft.Commit();
        }

        MoviePlayView(VideoItem vi)
        {
            this.videoItem = vi;
            this.reloadCount = 0;
            this.dataSource = DataStore.store.GetAllVideo().Take(20).ToList();
            // logger.Log("MoviePlayView ctor, ctx id", activity.ContentViewId, StartActivity.This.ContentViewId);
        }

        MyFragment CreateFragment()
        {
            myFragment = new MyFragment()
            {
                Title = "movieplay",
                MyOnCreateView = (frag, container) => CreateView(frag),
                MyOnDestroyView = (frag) => DestroyView(frag),
            };
            myFragment.MyOnResume = (f) =>
            {
                logger.Log("movie resume");
            };
            return myFragment;
        }

        public void DestroyView(MyFragment frag)
        {
            logger.Log("MovieView destroy");

            StopPlay();
        }

        public View CreateView(MyFragment frag)
        {

            var ctx = StartActivity.This;
            rootLayout = new LinearLayout(ctx)
            {
                Orientation = Android.Widget.Orientation.Vertical,
                Clickable = true,
                // Background = new ColorDrawable(Color.SaddleBrown),
            };
            rootLayout.SetBackgroundColor(Color.White);
            rootLayout.AddView(CreateTitleBar());

            CreateMovieView();
            CreateInfoView();

            Setup();
            Reload();

            var frameLayout = new FrameLayout(activity);
            frameLayout.AddView(GetListView(), new ViewGroup.LayoutParams(-1, -1));

            rootLayout.AddView(frameLayout);
            return rootLayout;
        }

        LinearLayout titleBarFLayout;
        View CreateTitleBar()
        {
            return Common.CreateTitleBar(new Common.TitleBarOption() { Title = "", });
        }

        TextView titleTextView;
        TextView[] viewInfoLabels;
        void CreateInfoView()
        {
            //邀请好友广告
            var adveriseLayout = new LinearLayout(activity);
            adveriseLayout.LayoutParameters = new LinearLayout.LayoutParams(-1, -1);
            adveriseLayout.SetGravity(GravityFlags.Center);
            adveriseLayout.SetBackgroundColor(Color.White);

            var adveriseImageView = new ImageView(activity);
            adveriseImageView.SetImageDrawable(Util.DrawableFromFile("adverise/YaoqingHaoyou.png"));
            var returnImageViewParams = new LinearLayout.LayoutParams(-1, 100);
            // returnImageViewParams.TopMargin = 15;
            returnImageViewParams.LeftMargin = 70;
            returnImageViewParams.RightMargin = 70;
            adveriseImageView.LayoutParameters = returnImageViewParams;
            adveriseLayout.AddView(adveriseImageView);

            adveriseLayout.Click += (s, e) =>
            {
                // 广告页面显示

            };
            insertItems.Add(new InsertItem()
            {
                view = adveriseLayout,
                    insertBefore = 0,
                    height = 120,
                    stickyHeight = 0,
            });

            //视频标题
            var viewTitleLayout = new LinearLayout(activity);
            viewTitleLayout.LayoutParameters = new LinearLayout.LayoutParams(-1, -1);
            viewTitleLayout.Orientation = Orientation.Horizontal;
            viewTitleLayout.SetHorizontalGravity(GravityFlags.CenterHorizontal);
            viewTitleLayout.SetBackgroundColor(Color.White);

            titleTextView = new TextView(activity);
            var titleTextViewParameters = new LinearLayout.LayoutParams(0, -1, 9);
            titleTextViewParameters.LeftMargin = 20;
            titleTextView.Gravity = GravityFlags.CenterVertical;
            titleTextView.LayoutParameters = titleTextViewParameters;
            titleTextView.Text = videoItem.vname;
            titleTextView.SetLines(1);
            viewTitleLayout.AddView(titleTextView);

            var titleImageView = new ImageView(activity);
            titleImageView.SetImageDrawable(Util.DrawableFromFile("category/Down.png"));
            var titleImageViewParams = new LinearLayout.LayoutParams(40, 20, 1);
            titleImageViewParams.TopMargin = 30;
            titleImageView.LayoutParameters = titleImageViewParams;
            viewTitleLayout.AddView(titleImageView);

            insertItems.Add(new InsertItem()
            {
                view = viewTitleLayout,
                    insertBefore = 0,
                    height = 80,
                    stickyHeight = 80,
            });

            //视频信息
            var viewInfoLayout = new LinearLayout(activity);
            viewInfoLayout.LayoutParameters = new LinearLayout.LayoutParams(-1, -1);
            viewInfoLayout.Orientation = Orientation.Horizontal;
            viewInfoLayout.SetBackgroundColor(Util.MainBKColor);
            var picItems = new string[]
            {
                "Dianzan.png",
                "Zhiboguankan.png",
                "Shoucang.png",
                "Zhuanfa.png"
            };
            viewInfoLabels = new TextView[]
            {
                new TextView(activity), new TextView(activity), new TextView(activity), new TextView(activity)
            };
            for (int i = 0; i < picItems.Length; i++)
            {
                var oneItemLayout = new LinearLayout(activity);
                oneItemLayout.LayoutParameters = new LinearLayout.LayoutParams(0, -1, 1);
                oneItemLayout.Orientation = Orientation.Vertical;
                oneItemLayout.SetGravity(GravityFlags.CenterHorizontal);
                //oneItemLayout.TextAlignment = TextAlignment.Center;
                viewInfoLayout.AddView(oneItemLayout);

                var oneItemImageView = new ImageView(activity);
                oneItemImageView.SetImageDrawable(Util.DrawableFromFile("category/" + picItems[i]));
                var oneItemImageViewParams = new LinearLayout.LayoutParams(80, 80);
                oneItemImageViewParams.TopMargin = 20;
                oneItemImageView.LayoutParameters = oneItemImageViewParams;
                oneItemLayout.AddView(oneItemImageView);

                var oneItemInfoParams = new LinearLayout.LayoutParams(-2, 70);
                viewInfoLabels[i].LayoutParameters = oneItemInfoParams;
                viewInfoLabels[i].TextAlignment = TextAlignment.Center;
                oneItemLayout.AddView(viewInfoLabels[i]);
            }
            viewInfoLabels[0].Text = videoItem.praises + "";
            viewInfoLabels[1].Text = videoItem.views + "";
            viewInfoLabels[2].Text = videoItem.favs + "";
            viewInfoLabels[3].Text = videoItem.forwords + "";

            insertItems.Add(new InsertItem()
            {
                view = viewInfoLayout,
                    insertBefore = 0,
                    height = 170,
                    stickyHeight = 0,
            });
        }

        protected override async void SelectItem(int idx)
        {
            StopPlay();

            videoItem = dataSource[idx];

            ReloadMovie();

            //非常奇葩的问题啊，如果在scroll过程中对stickyitem做了添删操作会crash
            //只能在滚动前临时屏蔽，之后再打开手动刷新一下
            var lastValue = hasStickyItem;
            hasStickyItem = false;
            recyclerView.ScrollToPosition(0);
            if (lastValue)
            {
                await Task.Delay(1);
                hasStickyItem = lastValue;
                updateSticky();
            }
            titleTextView.Text = videoItem.vname;
            viewInfoLabels[0].Text = videoItem.praises + "";
            viewInfoLabels[1].Text = videoItem.views + "";
            viewInfoLabels[2].Text = videoItem.favs + "";
            viewInfoLabels[3].Text = videoItem.forwords + "";
        }

        void StopPlay()
        {
            if (player != null)
            {
                player.Stop();
                player.Reset();
            }
            // mediaSource?.Close();
            tmUpdate?.Stop();

            if (reloadStartTime > 0)
            {
                long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                User.me.Notify("views", LitJson.JsonMapper.ToJson(new
                {
                    movieId = videoItem.vid,
                        movieName = videoItem.vname,
                        viewTime = reloadStartTime,
                        loadTime = reloadReadyTime,
                        viewDuration = (now - reloadStartTime) / 1000,
                }));
            }
        }

        long reloadStartTime;
        long reloadReadyTime;

        int pbcHeight = Util.dpToPx(30);
        void ReloadMovie()
        {
            SetPrepareState(PrepareState.Loading);

            var so = mb.ServiceLocator.Instance.Get<IStartOption>();
            var testCannotWatchVideo = so.GetBoolValue("testCannotWatchVideo");
            if (testCannotWatchVideo || !User.me.CanWatchVideo(videoItem.vid))
            {
                DemandFrequencyView.CreateFragment().Show(myFragment.FragmentManager, "demandFrequency");
                myFragment.FragmentManager.PopBackStack();
                return;
            }
            User.me.addVideoToHistory(videoItem.vid);
            User.me.NotifyViewVideo(videoItem.vid, videoItem.vname, (int) DateTimeOffset.Now.ToUnixTimeSeconds(), 0, 0);

            reloadStartTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            player = new MediaPlayer();
            // var url = "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4";
            // var url = $"http://localhost:{port}/movie/{movieInfo.vid}";
            var url = GlobalImpl.VideoServer.GetVideoUrl(videoItem.vid);
            logger.Log("movie load", url);

            player.SetDataSource(url);
            player.PrepareAsync();

            var rc = this.reloadCount;
            player.Prepared += (s, e) =>
            {
                logger.Log("movie prepared", rc, videoItem.vpath, Util.CurrentThreadId);
                reloadReadyTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();

                //检测视频宽高比，确定一个合适的窗口高度
                var rt = new Rect();
                recyclerView.GetDrawingRect(rt);
                double aspectRatio = (double) player.VideoHeight / player.VideoWidth;
                logger.Log("movie info", player.VideoWidth, player.VideoHeight, aspectRatio);
                logger.Log("window info", rt.Width(), rt.Height());
                int height = 0;
                var ins = insertItems.First();
                if (aspectRatio > 1)
                {
                    height = (int) (rt.Width() * aspectRatio);
                    height = Math.Min(height, (int) (rt.Height() * 0.8));
                    ins.height = height + pbcHeight;
                    ins.stickyHeight = ins.height / 2;
                }
                else
                {
                    height = (int) (rt.Width() * aspectRatio);
                    ins.height = height + pbcHeight;
                    ins.stickyHeight = ins.height;
                }
                Reload();
                ins.view.LayoutParameters = new FrameLayout.LayoutParams(-1, ins.height);

                SetPrepareState(PrepareState.Succeed);
                player.Start();
                startOnResume = true;
            };
            player.Error += (s, e) =>
            {
                if ((int) e.What == -38) return;
                logger.Log("movie error", rc, "error", e.What, e.Extra, videoItem.vpath);
                // if (e.What == MediaError.Io || e.What == MediaError.TimedOut || e.What == MediaError.ServerDied)
                SetPrepareState(PrepareState.Failure);
            };
            player.Completion += (s, e) =>
            {
                startOnResume = false;
            };
            player.BufferingUpdate += (s, e) =>
            {
                // logger.Log("buffer update", e.Percent);
                bufferingPercent = e.Percent;
            };
            player.Info += (s, e) =>
            {
                logger.Log("player info", e.What, e.Extra);
            };
            this.bufferingPercent = 0;
            this.reloadCount++;
        }

        async void CreateMovieView()
        {
            int height = 800;
            movieLayout = new FrameLayout(activity);
            movieLayout.Id = View.GenerateViewId();
            movieLayout.Tag = "movieLayout";

            insertItems.Add(new InsertItem()
            {
                view = movieLayout,
                    insertBefore = 0,
                    height = height,
                    stickyHeight = height / 2,
                    alwaysHang = true,
            });

            playerFragment = new MyFragment();
            myFragment.MyOnPause = delegate { if (player?.IsPlaying??false) player.Pause(); };
            playerFragment.MyOnResume = delegate { if (startOnResume) player?.Start(); };
            playerFragment.MyOnCreateView = (f, container) => OnMovieFragmentView(container);

            //这里要等list正常显示了，insertview被挂接后，才能将fragment添上去，所以等一会
            while (rootLayout.FindViewById(movieLayout.Id) == null)
            {
                logger.Log("wait for movieLayout");
                await Task.Delay(1);
            }
            SetMovieFragmentMode(MovieMode.InView);

            //这里又要等fragment挂接好了，才能取到其上的view以及loading子view，所以再等一会
            while (playerLayout == null)
            {
                logger.Log("wait for playerLayout");
                await Task.Delay(10);
            }
            ReloadMovie();
        }

        void SetMovieFragmentMode(MovieMode mode)
        {

            if (mode == movieMode) return;

            if (movieMode != MovieMode.None)
            {
                logger.Log("remove playerfragment");
                var fmgr = playerFragment.FragmentManager;
                fmgr.BeginTransaction().Remove(playerFragment).Commit();
                fmgr.ExecutePendingTransactions();
            }

            movieMode = mode;

            if (movieMode == MovieMode.FullScreen)
            {
                logger.Log("set playerfragment fullscreen");
                myFragment.FragmentManager
                    .BeginTransaction()
                    .Add(activity.ContentViewId, playerFragment)
                    .Commit();
            }
            else if (movieMode == MovieMode.InView)
            {
                logger.Log("set playerfragment inview");
                myFragment.ChildFragmentManager
                    .BeginTransaction()
                    .Replace(movieLayout.Id, playerFragment)
                    // ft.AddToBackStack("playInView"); //这里绝对不能添加backstack，否则切换全屏时会报错，估计是被容器引用住了
                    .Commit();
            }

            //调整朝向和全屏标志
            bool full = movieMode == MovieMode.FullScreen;
            activity.RequestedOrientation = full?ScreenOrientation.Landscape : ScreenOrientation.Portrait;
            activity.Window.SetFlags(full?WindowManagerFlags.Fullscreen : 0, WindowManagerFlags.Fullscreen);
        }

        View OnMovieFragmentView(ViewGroup container)
        {
            if (playerLayout == null)
            {
                playerLayout = new FrameLayout(activity);
                playerLayout.SetBackgroundColor(Color.Black);

                var pb = new ProgressBar(activity)
                {
                    Visibility = ViewStates.Invisible,
                    LayoutParameters = new FrameLayout.LayoutParams(100, 100) { Gravity = GravityFlags.Center },
                };
                pb.SetParent(playerLayout);
                pb.IndeterminateDrawable.SetColorFilter(Util.MainColor, PorterDuff.Mode.SrcIn);

                new TextView(activity)
                {
                    Text = "加载失败，点击重试",
                        Visibility = ViewStates.Invisible,
                        Gravity = GravityFlags.Center,
                        TextSize = 20,
                        // Background = new ColorDrawable(Color.White),
                        // LayoutParameters = new FrameLayout.LayoutParams(-2, -2),
                }.SetParent(playerLayout).SetTextColor(Util.MainColor);

                playerLayout.Click += (s, e) =>
                {
                    logger.Log("click playerview");
                    if (prepareState == PrepareState.Failure)
                    {
                        StopPlay();
                        ReloadMovie();
                    }
                    else if (prepareState == PrepareState.Succeed) { }
                };

                if (player != null) CreateSurfaceView(playerLayout);

                playerLayout.KeyPress += (s, e) =>
                {
                    if (movieMode == MovieMode.FullScreen)
                    {
                        logger.Log("keypress", container.Id, container == s, e.KeyCode, e.Event.Action);
                        if (e.KeyCode == Keycode.Back)
                        {
                            SetMovieFragmentMode(MovieMode.InView);
                        }
                    }
                };
            }

            bool full = movieMode == MovieMode.FullScreen;
            if (full) //全屏模式时调整playerLayout布局也独占全屏
            {
                playerLayout.LayoutParameters = new ViewGroup.LayoutParams(-1, -1);
                playerLayout.FocusableInTouchMode = true;
                playerLayout.RequestFocus();
            }
            else
            {
                playerLayout.LayoutParameters = new ViewGroup.LayoutParams(-1, -1);
                playerLayout.FocusableInTouchMode = false;
                playerLayout.ClearFocus();

            }

            logger.Log("CreatePlayerView", container.Id, movieMode, full);
            return playerLayout;

        }

        void UpdateAspect(TextureView view)
        {
            double aspectRatio = (double) player.VideoHeight / player.VideoWidth;
            int viewWidth = view.Width, viewHeight = view.Height;

            int newWidth, newHeight;

            if (viewHeight > (int) (viewWidth * aspectRatio))
            {
                newWidth = viewWidth;
                newHeight = (int) (viewWidth * aspectRatio);
            }
            else
            {
                newWidth = (int) (viewHeight / aspectRatio);
                newHeight = viewHeight;
            }
            int xoff = (viewWidth - newWidth) / 2;
            int yoff = (viewHeight - newHeight) / 2;
            var txform = new Matrix();
            view.GetTransform(txform);
            txform.SetScale((float) newWidth / viewWidth, (float) newHeight / viewHeight);
            txform.PostTranslate(xoff, yoff);
            view.SetTransform(txform);
        }

        void CreateSurfaceView(ViewGroup container)
        {
            var linear = new LinearLayout(activity) { Orientation = Orientation.Vertical };
            linear.LayoutParameters = new ViewGroup.LayoutParams(-1, -1);
            linear.SetBackgroundColor(Color.Black);
            linear.SetParent(container);

            var view = new TextureView(activity);
            view.LayoutParameters = new LinearLayout.LayoutParams(-1, -1, 1);
            view.SetParent(linear);

            SurfaceTexture usingTexture = null;
            view.SurfaceTextureAvailable += (s, e) =>
            {
                logger.Log("surface available, has tex:", usingTexture == null);
                UpdateAspect(view);
                if (usingTexture == null)
                {
                    usingTexture = e.Surface;
                    player.SetSurface(new Surface(usingTexture));
                }
                else
                {
                    view.SurfaceTexture = usingTexture;
                }
            };
            view.SurfaceTextureDestroyed += (s, e) =>
            {
                logger.Log("surface destroyed");
                //注：这里必须返回false，否则TextureView会将关联的Texture销毁，导致player要重新初始化，进度可能倒退
                e.Handled = false;
            };
            view.SurfaceTextureSizeChanged += (s, e) =>
            {
                logger.Log("surface change", e.Width, e.Height);
                UpdateAspect(view);
            };

            linear.AddView(CreateController(), new LinearLayout.LayoutParams(-1, pbcHeight));
        }

        void SetPrepareState(PrepareState state)
        {
            logger.Log("SetPrepareState", state, playerLayout);
            var loadingView = playerLayout.GetChildAt(0) as ProgressBar;
            var tipView = playerLayout.GetChildAt(1) as TextView;

            if (state == PrepareState.Loading)
            {
                loadingView.Visibility = ViewStates.Visible;
                tipView.Visibility = ViewStates.Invisible;
                while (playerLayout.ChildCount > 2)
                    playerLayout.RemoveViewAt(2);

            }
            else if (state == PrepareState.Succeed)
            {
                loadingView.Visibility = ViewStates.Invisible;
                tipView.Visibility = ViewStates.Invisible;
                CreateSurfaceView(playerLayout);
            }
            else if (state == PrepareState.Failure)
            {
                loadingView.Visibility = ViewStates.Invisible;
                tipView.Visibility = ViewStates.Visible;
            }

            prepareState = state;

        }

        bool isDragging;
        View CreateController()
        {
            var pbcView = new LinearLayout(activity)
            {
                Orientation = Orientation.Horizontal,
            };
            pbcView.SetVerticalGravity(GravityFlags.Center);
            pbcView.SetBackgroundColor(Color.Argb(200, 0, 0, 0));
            // parent.AddView(pbcView, new FrameLayout.LayoutParams(-1, 150) { Gravity = GravityFlags.Bottom });

            var btn = new ImageButton(activity);
            var bs = Util.dpToPx(30);
            btn.LayoutParameters = new LinearLayout.LayoutParams(bs, bs) { LeftMargin = Util.dpToPx(10), };
            btn.SetParent(pbcView);
            btn.SetPadding(0, 0, 0, 0);
            btn.SetBackgroundResource(0);
            // btn.SetBackgroundColor(Color.Blue);
            btn.SetForegroundGravity(GravityFlags.Bottom);
            btn.SetImageDrawable(
                Util.MakeDrawableSelector(
                    Util.MakeDrawable("slider/play.png").WithColor(Util.MainColor),
                    selected : Util.MakeDrawable("slider/pause.png").WithColor(Util.MainColor)
                )
            );
            btn.SetScaleType(ImageView.ScaleType.FitXy);
            btn.Selected = true;
            btn.Click += (s, e) =>
            {
                if (player != null)
                {
                    if (player.IsPlaying)
                        player.Pause();
                    else
                        player.Start();
                }
            };

            var seekbar = new SeekBar(activity);
            seekbar.LayoutParameters = new LinearLayout.LayoutParams(0, -1, 1);
            seekbar.SetParent(pbcView);
            seekbar.Thumb.SetColorFilter(Util.MainColor, PorterDuff.Mode.SrcIn);
            seekbar.ProgressBackgroundTintList = Util.MakeColorStateList(Util.MainBKColor);
            seekbar.ProgressTintList = Util.MakeColorStateList(Util.MainColor);
            seekbar.SecondaryProgressTintList = Util.MakeColorStateList(new Color((int) (Util.MainColor * 0.8)));
            seekbar.ProgressChanged += (s, e) =>
            {
                // logger.Log("progress", e.FromUser, e.Progress);
                if (e.FromUser)
                {
                    if ((int) Android.OS.Build.VERSION.SdkInt >= 26)
                        player.SeekTo(e.Progress, MediaPlayerSeekMode.Closest);
                    else
                        player.SeekTo(e.Progress);
                }
            };
            seekbar.StartTrackingTouch += delegate { isDragging = true; };
            seekbar.StopTrackingTouch += delegate { isDragging = false; };

            var labTime = new TextView(activity)
            {
                TextAlignment = TextAlignment.Center,
                Gravity = GravityFlags.Center,
            };
            labTime.SetParent(pbcView);
            // labTime.SetBackgroundColor(Color.Blue);
            labTime.SetTextColor(Color.White);
            labTime.SetTypeface(Typeface.Create("monospace", TypefaceStyle.Normal), TypefaceStyle.Normal);
            labTime.LayoutParameters = new LinearLayout.LayoutParams(-2, -1);
            labTime.Text = "10:20:30";

            var btnFullscreen = new ImageButton(activity);
            btnFullscreen.LayoutParameters = new LinearLayout.LayoutParams(bs, bs)
            {
                LeftMargin = Util.dpToPx(10),
                RightMargin = Util.dpToPx(10),
            };
            btnFullscreen.SetParent(pbcView);
            btnFullscreen.SetPadding(0, 0, 0, 0);
            btnFullscreen.SetBackgroundResource(0);
            // btn.SetBackgroundColor(Color.Blue);
            btnFullscreen.SetForegroundGravity(GravityFlags.Bottom);
            btnFullscreen.SetImageDrawable(
                Util.MakeDrawableSelector(
                    Util.MakeDrawable("slider/full.png").WithColor(Util.MainColor)
                    // selected : Util.MakeDrawable("slider/pause.png").WithColor(Util.MainColor)
                )
            );
            btnFullscreen.SetScaleType(ImageView.ScaleType.FitXy);
            btnFullscreen.Selected = true;
            btnFullscreen.Click += (s, e) =>
            {
                btnFullscreen.Selected ^= true;
                SetMovieFragmentMode(movieMode.toggle());
            };

            tmUpdate?.Stop();
            tmUpdate = new System.Timers.Timer() { Interval = 100, Enabled = true };
            tmUpdate.Elapsed += (s, e) =>
            {
                activity.RunOnUiThread(() =>
                {
                    UpdateController(pbcView);
                });
            };
            UpdateController(pbcView);

            return pbcView;
        }

        void UpdateController(ViewGroup pbcView)
        {
            if (player == null) return;

            var btnPlay = pbcView.GetChildAt(0) as ImageButton;
            btnPlay.Selected = player.IsPlaying;

            var seekbar = pbcView.GetChildAt(1) as SeekBar;
            seekbar.Max = player.Duration;
            seekbar.SecondaryProgress = (int) (seekbar.Max * bufferingPercent / 100);
            seekbar.Progress = player.CurrentPosition;
            // long from = player.CurrentPosition / player.Duration * mediaSource.Size;
            // long bufferingMax = mediaSource.GetAvailableLength(from);
            // seekbar.SecondaryProgress = (int) (seekbar.Max * bufferingMax / mediaSource.Size);
            // logger.Log("available length", bufferingMax);

            var labTime = pbcView.GetChildAt(2) as TextView;
            labTime.Text = Util.FormatTime(player.CurrentPosition);

            // logger.Log("updatecontroller", player.CurrentPosition, player.Duration);
        }

    };

}